package ch.ethz.fcl.metrobuzz.data.ltt.node;

import java.util.ArrayList;
import java.util.List;

import ch.ethz.fcl.metrobuzz.MBContainer;
import ch.ethz.fcl.metrobuzz.data.MBData;
import ch.ethz.fcl.metrobuzz.data.ltt.TrajectoryGraph;
import ch.ethz.fcl.metrobuzz.data.scene.basemap.Node;

/**
 * Long Term Trajectory Node records all the transactions in a node
 * 
 * @author Zeng Wei
 * @email zeng@arch.ethz.ch
 * 
 */
public class LTTNode {
	private MBContainer container = null;
	private MBData data = null;

	private TrajectoryGraph trajGraph;
	private int nodeId;
	private float distToSelectedNode = -1; // shortest distance to the selected
											// node
	private int level = -1; // selected node level 0, recursively increase as a
							// tree hierarchy

	private int degree = -1; // records how many connected frequent ltt nodes

	private LTTNodeInterchange ai = null;

	// indices of trajectories that start from this node
	private List<Integer> startTrajIndices;

	public LTTNode(MBContainer container, TrajectoryGraph trajGraph, int nodeId) {
		this.container = container;
		this.data = container.getData();
		this.trajGraph = trajGraph;

		this.nodeId = nodeId;

		this.ai = new LTTNodeInterchange(this.container, trajGraph, this);
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public void setDistToSelectedNode(float dist) {
		this.distToSelectedNode = dist;
	}

	public void addStartTrajIndices(List<Integer> input) {
		this.startTrajIndices = new ArrayList<Integer>();
		this.startTrajIndices.addAll(input);
	}

	public Node toNode() {
		return data.getScene().getNode(nodeId);
	}

	public int getId() {
		return this.nodeId;
	}

	public int getLevel() {
		return this.level;
	}

	public float getDistToSelectedNode() {
		return this.distToSelectedNode;
	}

	public LTTNodeInterchange getInterchange() {
		return ai;
	}

	public MBData getData() {
		return this.data;
	}

	public int getDegree() {
		if (degree == -1) {
			if (trajGraph.getFrequentLTT() == null)
				degree = toNode().getDegree();

			List<LTTNode> frequentNodes = trajGraph.getFrequentLTT()
					.getFrequentNodes();

			if (frequentNodes == null)
				degree = toNode().getDegree();
			else {
				degree = 0;
				List<Integer> connectedNodeIds = ai.getConnectedNodeIds();
				for (int i = 0; i < connectedNodeIds.size(); i++) {
					if (connectedNodeIds.get(i) == nodeId)
						continue;

					LTTNode connectLTTNode = trajGraph.getSelectedLTTNodeMap()
							.get(connectedNodeIds.get(i));
					if (connectLTTNode != null
							&& frequentNodes.contains(connectLTTNode))
						degree++;
				}
			}
		}

		return degree;
	}

	public float getSum() {
		return getInterchange().getCircos().getData().getTotalSum();
	}

	public List<Integer> getStartTrajIndices() {
		return startTrajIndices;
	}

	public TrajectoryGraph getTrajGraph() {
		return trajGraph;
	}

	@Override
	public boolean equals(Object o) {
		if (!(o instanceof LTTNode))
			return false;
		if (((LTTNode) o).getId() == this.nodeId)
			return true;
		return false;
	}
}
